home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
RTF
/
xtextview.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
8KB
|
398 lines
/* $Header: /usr/people/pcd/Src/RTF/RCS/xtextview.C,v 1.1 92/11/23 12:58:57 pcd Exp Locker: pcd $
*/
#include "xtextview.h"
extern "C" {
#include "xtextview_c.h"
#include "image.h"
};
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <stdio.h>
/* This code is relatively stable. */
#define DEBUG 0
int debug_x = 0;
#include "debug.h"
void*
XTextView_create(Display* disp, void* widget)
{
return new XTextView(*disp, widget);
}
void
XTextView_destroy(void* v)
{
delete ((XTextView*)v);
}
int
XTextView_string(void* v, const char* s, int e)
{
return ((XTextView*)v)->string(s, e);
}
void
XTextView_resize(void* v, int x, int y, int w, int h)
{
((XTextView*)v)->resize(x, y, w, h);
}
void
XTextView_drawable(void* v, Drawable d, int depth)
{
((XTextView*)v)->drawable(d, depth);
}
void
XTextView_render(void* v, int x, int y, int w, int h)
{
((XTextView*)v)->render(x, y, w, h);
}
int
XTextView_region(void* v, long first, long last, int x[4], int y[4])
{
return ((XTextView*)v)->region(first, last, x, y);
}
int
XTextView_locate(void* v, long pos, int* top, int* bot)
{
return ((XTextView*)v)->locate(pos, top, bot);
}
int
XTextView_height(void* v)
{
return ((XTextView*)v)->page_height();
}
int
XTextView_width(void* v)
{
return ((XTextView*)v)->width();
}
long
XTextView_position(void* v, int x, int y)
{
return ((XTextView*)v)->position(x, y);
}
char*
XTextView_plain_text(const char* rt, long q)
{
return View::plain_text(rt, q);
}
XTextView::XTextView(Display& d, void* widget)
: View()
{
display_ = &d;
drawable_ = 0;
widget_ = widget;
}
XFontStruct*
XTextView::font(char* spec) const
{
return Widget_font(widget_, spec);
}
GC
XTextView::get_gc(unsigned long mask, XGCValues& v)
{
return Widget_get_gc(widget_, mask, &v);
}
void
XTextView::free_gc(GC gc)
{
Widget_free_gc(widget_, gc);
}
Pixel
XTextView::color(int red, int green, int blue) const
{
return Widget_color(widget_, red, green, blue);
}
void
XTextView::text_flow(TextFlow& parent, TextPosition f, TextPosition l,
const CharacterFormat& cf)
{
new XTextFlow(parent, f, l, *this, cf);
}
void
XTextView::text_char(TextFlow& parent, TextPosition f, TextPosition l, char c,
const CharacterFormat& cf)
{
new XTextFlow(parent, f, l, *this, cf, c);
}
void
XTextView::new_line(TextFlow& parent, TextPosition f, TextPosition l,
Inches sa)
{
new XNewLineFlow(parent, f, l, *this, sa);
}
void
XTextView::drawable(Drawable d, unsigned int depth)
{
if(d != drawable()){
drawable_ = d;
depth_ = depth;
clear();
}
}
void
XTextView::clear()
{
if(drawable())
XClearArea(display(), drawable(), 0, 0, 0, 0, 1);
}
int
XTextView::render(Coord x, Coord y, Coord w, Coord h)
{
REQUIRE(drawable() && format(), return 0);
BRect r(x, y, w, h);
page_->render(r);
return 1;
}
int
XTextView::region(TextPosition f, TextPosition l, Coord x[4], Coord y[4])
{
REQUIRE(drawable() && format(), return 0);
x[0] = bounds_.left();
x[3] = bounds_.right();
assert(f<l);
x[1] = page_->locate(f, &y[0], &y[1]); // textrect::locate@@
x[2] = page_->locate(l, &y[2], &y[3]);
return 1;
}
int
XTextView::locate(TextPosition pos, int* top, int* bot)
{
REQUIRE(drawable() && format(), return 0);
return page_->locate(pos, top, bot);
}
XTextFlow::XTextFlow(TextFlow& parent, TextPosition first, TextPosition last,
XTextView& view, const CharacterFormat& cf, char c)
: TextFlow(parent, first, last)
{
view_ = &view;
c_ = c;
ul_ = cf.underline;
super_ = cf.super;
sub_ = cf.sub;
static char spec[80];
static char* faces[] =
{"nil", "roman", "swiss", "modern", "script", "decor", "tech"};
strcpy(spec, faces[cf.font_family]);
if(cf.bold)
strcat(spec, "-bold");
if(cf.italic)
strcat(spec, "-italic");
#ifdef FONT_SIZES
if(cf.size != 24)
sprintf(spec + strlen(spec), "-%d", cf.size/2);
#endif
font_ = view.font(spec);
XGCValues values;
unsigned long valuemask;
values.function = GXcopy;
values.foreground = cf.fg_pixel;
values.font = font()->fid;
valuemask = GCFunction | GCForeground | GCFont;
gc_ = view.get_gc(valuemask, values);
}
XTextFlow::~XTextFlow()
{
view_->free_gc(gc_);
}
Qty
XTextFlow::character_shape(TextPosition pos, Qty q,
Extent avail, Extent& used, int whole)
const
{
if(avail.right() - avail.current_x() < 2)
return 0; // optimization
XCharStruct ext;
int ascent;
int descent;
int dir;
/* for single (escaped) characters */
if(c_){
char x = c_; // appease the compiler
XTextExtents(font(), &x, 1,
&dir, &ascent, &descent, &ext);
if(ascent + descent < avail.bottom()-avail.top() &&
ext.width < avail.right() - avail.current_x()){
used.x2 = 0; //left over to justify
((XTextFlow*)this)->width(used.x0 = ext.width); // get around compiler
used.y0 = ascent;
used.y1 = descent;
return q;
}else
return 0;
}
const Byte* text = data() + pos;
assert(q>0);
assert(avail.right() >= avail.current_x());
assert(avail.current_x() >= avail.width());
assert(avail.right() > avail.width());
/*@# BREAK_CHARS should be a resource */
# define BREAK_CHARS " -"
XTextExtents(font(), (char*)text, (int)q, /* @# int! */
&dir, &ascent, &descent, &ext);
ascent += super_;
descent += sub_;
REQUIRE(ascent + descent <= avail.bottom() - avail.top(),
return 0);
while(ext.width > avail.right() - avail.current_x()){
if(whole)
while(--q>0 && strchr(BREAK_CHARS, text[q-1]) == 0)
;
else
q--;
if(q == 0)
return 0;
XTextExtents(font(), (char*)text, (int)q, /*@# int! */
&dir, &ascent, &descent, &ext);
}
used.x2 = 0; //left over to justify
((XTextFlow*)this)->width(used.x0 = ext.width); // get around compiler
used.y0 = ascent;
used.y1 = descent;
return q;
}
void
XTextFlow::render(TextPosition pos, Qty q, Point p) const
{
REQUIRE(display() && drawable(), return);
const Byte* text = data() + pos;
Coord y = p.y + - super_ + sub_;
if(c_){
char x = c_; //appease compiler
XDrawString(display(), drawable(), gc(), p.x, y,
&x, (int)1);
}
else
XDrawString(display(), drawable(), gc(), p.x, y, (char*)text, (int)q);
// HEURISTIC: underlines 2 pixels below baseline
if(ul_)
XDrawLine(display(), drawable(), gc(), p.x, y+2, p.x+width_, y+2);
}
void
XTextView::picture(TextFlow& p, TextPosition f, TextPosition l,
Coord w, Coord h)
{
new XBitMap(p, f, l, *this, w, h);
}
XBitMap::XBitMap(TextFlow& p, TextPosition f, TextPosition l,
XTextView& v, int width, int height)
: TextFlow(p, f, l)
{
view_ = &v;
width_ = width;
height_ = height;
pixmap_ = None;
}
XBitMap::~XBitMap()
{
if(pixmap_ != None)
XFreePixmap(view_->display(), pixmap_);
}
Qty
XBitMap::character_shape(TextPosition, Qty q,
Extent avail, Extent& used, int) const
{
if(avail.right() - avail.current_x() < width_
|| avail.bottom() - avail.top() < height_)
return 0;
used.x0 = width_;
used.x2 = 0;
used.ascent(height_);
used.descent(0);
return q;
}
int
XBitMap::get_pixmap()
{
static builder_inited = 0;
if(!builder_inited){
if(!initializeImageBuilder(view_->display()))
return 0;
builder_inited = 1;
}
if(pixmap_ != None)
return 1;
else if(pixmap_ = createPixmapFromHexData(view_->display(),
view_->drawable(),
(const char*)data()))
return 1;
else
return 0;
}
void
XBitMap::render(TextPosition, Qty, Point p) const
{
if(((XBitMap*)this)->get_pixmap()) // appease compiler
//@@ don't copy the whole thing! just the exposed parts.
//@@ unfortunately, we don't have that info here.
XCopyArea(view_->display(), pixmap_, view_->drawable(),
view_->default_gc(), 0, 0, width_, height_, p.x, p.y - height_);
}